/*
 *    Copyright (c) 2018-2025, boss All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the boss developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: boss
 */
package com.hopes.bizz.close.visitor.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.hopes.bizz.close.basic.service.ClosedOperateAuditRecordService;
import com.hopes.bizz.close.common.constant.BasicDicConstant;
import com.hopes.bizz.close.common.constant.CloseModuleEnums;
import com.hopes.bizz.close.common.constant.VisitorDicConstant;
import com.hopes.bizz.close.common.constant.enums.ParkCloseSysDictEnum;
import com.hopes.bizz.close.visitor.dto.ClosedVisitorApplyAuditDTO;
import com.hopes.bizz.close.visitor.dto.ClosedVisitorApplyDTO;
import com.hopes.bizz.close.visitor.dto.ClosedVisitorApplyExcelDTO;
import com.hopes.bizz.close.visitor.entity.ClosedVisitorApplyEntity;
import com.hopes.bizz.close.visitor.mapper.ClosedVisitorApplyMapper;
import com.hopes.bizz.close.visitor.service.ClosedVisitorApplyService;
import com.hopes.bizz.close.visitor.vo.ClosedVisitorApplyExcelVO;
import com.hopes.boss.admin.api.resolver.DictResolver;
import com.hopes.boss.admin.api.resolver.enums.AdminDictEnum;
import com.hopes.boss.common.data.org.OrgContextHolder;
import com.hopes.boss.common.entity.ValidateImportBO;
import com.hopes.boss.common.excel.vo.ErrorMessage;
import com.hopes.boss.common.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
/**
 * 访客进出申请
 *
 * @author pig
 * @date 2023-10-25 13:26:19
 */
@Service
@RequiredArgsConstructor
public class ClosedVisitorApplyServiceImpl extends ServiceImpl<ClosedVisitorApplyMapper, ClosedVisitorApplyEntity> implements ClosedVisitorApplyService {

    private final ClosedOperateAuditRecordService closedOperateAuditRecordService;

    @Override
    public boolean save(ClosedVisitorApplyEntity entity) {
        entity.setApplyUserId(SecurityUtils.getUserId());
        if (ObjUtil.isNull(entity.getApplyTime())) {
            entity.setApplyTime(Calendar.getInstance().getTime());
        }
        entity.setAuditStatus(VisitorDicConstant.CLOSE_VISITOR_AUDIT_STATUS_NOT_SUBMIT);
        return SqlHelper.retBool(getBaseMapper().insert(entity));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean submitById(Long id) {
        // 1、修改状态
        lambdaUpdate()
                .set(ClosedVisitorApplyEntity::getAuditStatus, BasicDicConstant.CLOSE_VISITOR_AUDIT_STATUS_NOT_AUDIT)
                .eq(ClosedVisitorApplyEntity::getId, id).update();
        // 2、创建提交日志记录
        return closedOperateAuditRecordService.buildSaveOperateAuditRecord(id,
                CloseModuleEnums.GeneralCarOperateEnum.submit.getValue(),
                BasicDicConstant.CLOSE_GENERAL_CAR_AUDIT_STATUS_NOT_AUDIT, null, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveAndSubmit(ClosedVisitorApplyEntity closedVisitorApply) {
        // 1、保存访客申请
        closedVisitorApply.setApplyUserId(SecurityUtils.getUserId());
        if (ObjUtil.isNull(closedVisitorApply.getApplyTime())) {
            closedVisitorApply.setApplyTime(Calendar.getInstance().getTime());
        }
        closedVisitorApply.setAuditStatus(VisitorDicConstant.CLOSE_VISITOR_AUDIT_STATUS_NOT_AUDIT);
        if (ObjUtil.isNull(closedVisitorApply.getId())) {
            getBaseMapper().insert(closedVisitorApply);
        } else {
            getBaseMapper().updateById(closedVisitorApply);
        }
        // 2、创建 && 提交日志
        return closedOperateAuditRecordService.buildSaveOperateAuditRecord(closedVisitorApply.getId(),
                CloseModuleEnums.GeneralCarOperateEnum.audit.getValue(),
                BasicDicConstant.CLOSE_GENERAL_CAR_AUDIT_STATUS_NOT_AUDIT, null, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean auditById(ClosedVisitorApplyAuditDTO closedVisitorApplyAuditDTO) {
        // 1、修改对象
        lambdaUpdate()
                .set(ClosedVisitorApplyEntity::getRemark, closedVisitorApplyAuditDTO.getRemark())
                .set(ClosedVisitorApplyEntity::getAuditStatus, closedVisitorApplyAuditDTO.getAuditStatus())
                .set(ClosedVisitorApplyEntity::getAuditStatusDesc, closedVisitorApplyAuditDTO.getAuditStatusDesc())
                .eq(ClosedVisitorApplyEntity::getId, closedVisitorApplyAuditDTO.getId()).update();
        // 2、创建 && 提交日志
        return closedOperateAuditRecordService.buildSaveOperateAuditRecord(
                closedVisitorApplyAuditDTO.getId(),
                CloseModuleEnums.GeneralCarOperateEnum.audit.getValue(),
                closedVisitorApplyAuditDTO.getAuditStatus(), closedVisitorApplyAuditDTO.getAuditStatusDesc(), closedVisitorApplyAuditDTO.getRemark());
    }

    @Override
    public IPage<ClosedVisitorApplyEntity> queryAppVisitorApplyPage(Page page, ClosedVisitorApplyDTO closedVisitorApplyDTO) {
        final LambdaQueryWrapper<ClosedVisitorApplyEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ClosedVisitorApplyEntity::getApplyUserId, SecurityUtils.getUserId());
        wrapper.eq(ObjUtil.isNotNull(closedVisitorApplyDTO.getOrgId()), ClosedVisitorApplyEntity::getOrgId, closedVisitorApplyDTO.getOrgId());
        wrapper.eq(ObjUtil.isNotNull(closedVisitorApplyDTO.getAuditStatus()), ClosedVisitorApplyEntity::getAuditStatus, closedVisitorApplyDTO.getAuditStatus());
        wrapper.eq(ObjUtil.isNotNull(closedVisitorApplyDTO.getVisitPurpose()), ClosedVisitorApplyEntity::getVisitPurpose, closedVisitorApplyDTO.getVisitPurpose());
        wrapper.gt(ObjUtil.isNotNull(closedVisitorApplyDTO.getStartTime()), ClosedVisitorApplyEntity::getEffectiveTime, closedVisitorApplyDTO.getStartTime());
        wrapper.lt(ObjUtil.isNotNull(closedVisitorApplyDTO.getEndTime()), ClosedVisitorApplyEntity::getEffectiveTime, closedVisitorApplyDTO.getEndTime());
        wrapper.like(StrUtil.isNotBlank(closedVisitorApplyDTO.getKeyword()), ClosedVisitorApplyEntity::getName, closedVisitorApplyDTO.getKeyword())
                .or().like(StrUtil.isNotBlank(closedVisitorApplyDTO.getKeyword()), ClosedVisitorApplyEntity::getPhone, closedVisitorApplyDTO.getKeyword())
                .or().like(StrUtil.isNotBlank(closedVisitorApplyDTO.getKeyword()), ClosedVisitorApplyEntity::getIdNum, closedVisitorApplyDTO.getKeyword());
        wrapper.orderByDesc(ClosedVisitorApplyEntity::getApplyTime);
        return this.page(page, wrapper);
    }

    @Override
    public IPage<ClosedVisitorApplyEntity> queryAppVisitorAuditPage(Page page, List<Integer> auditStatusList, ClosedVisitorApplyDTO closedVisitorApplyDTO) {
        final LambdaQueryWrapper<ClosedVisitorApplyEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.in(CollUtil.isNotEmpty(auditStatusList), ClosedVisitorApplyEntity::getAuditStatus, auditStatusList);
        wrapper.eq(ObjUtil.isNotNull(closedVisitorApplyDTO.getAuditStatus()), ClosedVisitorApplyEntity::getAuditStatus, closedVisitorApplyDTO.getAuditStatus());
        wrapper.eq(ObjUtil.isNotNull(closedVisitorApplyDTO.getOrgId()), ClosedVisitorApplyEntity::getOrgId, closedVisitorApplyDTO.getOrgId());
        wrapper.eq(ObjUtil.isNotNull(closedVisitorApplyDTO.getVisitPurpose()), ClosedVisitorApplyEntity::getVisitPurpose, closedVisitorApplyDTO.getVisitPurpose());
        wrapper.gt(ObjUtil.isNotNull(closedVisitorApplyDTO.getStartTime()), ClosedVisitorApplyEntity::getEffectiveTime, closedVisitorApplyDTO.getStartTime());
        wrapper.lt(ObjUtil.isNotNull(closedVisitorApplyDTO.getEndTime()), ClosedVisitorApplyEntity::getEffectiveTime, closedVisitorApplyDTO.getEndTime());
        wrapper.like(StrUtil.isNotBlank(closedVisitorApplyDTO.getKeyword()), ClosedVisitorApplyEntity::getName, closedVisitorApplyDTO.getKeyword())
                .or().like(StrUtil.isNotBlank(closedVisitorApplyDTO.getKeyword()), ClosedVisitorApplyEntity::getPhone, closedVisitorApplyDTO.getKeyword())
                .or().like(StrUtil.isNotBlank(closedVisitorApplyDTO.getKeyword()), ClosedVisitorApplyEntity::getIdNum, closedVisitorApplyDTO.getKeyword());
        wrapper.orderByDesc(ClosedVisitorApplyEntity::getApplyTime);
        return this.page(page, wrapper);
    }

    @Override
    public ValidateImportBO<ClosedVisitorApplyExcelDTO> validateImport(List<ClosedVisitorApplyExcelDTO> excelDTOList) {
        ValidateImportBO<ClosedVisitorApplyExcelDTO> bo = new ValidateImportBO<>();
        List<ErrorMessage> errorMessageList = new ArrayList<>();
        List<ClosedVisitorApplyExcelDTO> saveList = new ArrayList<>();
        int successNum = 0;
        int failedNum = 0;

        bo.setErrorMessages(errorMessageList);
        bo.setSaveList(saveList);
        bo.setSuccessNum(successNum);
        bo.setFailedNum(failedNum);
        return bo;
    }

    @Override
    public ClosedVisitorApplyEntity importDtoToEntity(ClosedVisitorApplyExcelDTO excelDto) {
        ClosedVisitorApplyEntity entity= new ClosedVisitorApplyEntity();
        BeanUtils.copyProperties(excelDto, entity);
        return entity;
    }

    @Override
    public ClosedVisitorApplyExcelVO exportEntityToVo(ClosedVisitorApplyEntity entity) {
        ClosedVisitorApplyExcelVO excelVO = new ClosedVisitorApplyExcelVO();
        BeanUtils.copyProperties(entity, excelVO);
        excelVO.setOrgIdStr(DictResolver.getItemLabelByValue(AdminDictEnum.sys_company, entity.getOrgId()));
        excelVO.setVisitTypeStr(DictResolver.getItemLabelByValue(ParkCloseSysDictEnum.close_visitor_type, entity.getVisitType()));
        excelVO.setApplyTypeStr(DictResolver.getItemLabelByValue(ParkCloseSysDictEnum.close_visitor_apply_type, entity.getApplyType()));
        excelVO.setVisitPurposeStr(DictResolver.getItemLabelByValue(ParkCloseSysDictEnum.close_visitor_purpose, entity.getVisitPurpose()));
        excelVO.setAuditStatusStr(DictResolver.getItemLabelByValue(ParkCloseSysDictEnum.close_visitor_audit_status, entity.getAuditStatus()));
        return excelVO;
    }
}
